<cffunction name="goto">
	<cfargument name="args" /><cfset var i = 0 />
	<cfscript>
	if ( not structKeyExists( application, "goto" ) or ( isStruct(args) and structKeyExists( args, "reload" ) ) ) {
		application.goto = { beforeEvent = "", afterEvent = "", controllers = {}, production = true, showTrace = false };
		application.goto.controllerPkg = cgi.script_name; application.goto.controllerPkg = listDeleteAt(application.goto.controllerPkg, listLen(application.goto.controllerPkg, "/"), "/");
		application.goto.beans = application.goto.controllerPkg & "/ColdSpring.xml";
		application.goto.viewDir = application.goto.controllerPkg & "/views";
		application.goto.controllerPkg = application.goto.controllerPkg & "/controllers";
		if ( isStruct( args ) ) for ( i in args ) { application.goto[i] = args[i]; }
		if ( not structKeyExists( application.goto, "defaultEvent" ) ) application.goto.defaultEvent = "home.home";
		if ( not structKeyExists( application.goto, "beanFactory" ) ) application.goto.beanFactory = createObject( "component", "coldspring.beans.DefaultXmlBeanFactory" );
		if ( fileExists( expandPath( application.goto.beans ) ) ) application.goto.beanFactory.loadBeans( application.goto.beans );
	}
	if ( not structKeyExists( request, "goingTo" ) ) {
		request.goingTo = { out = "", trace = [], start = getTickCount() };
		if ( structKeyExists( cgi, "path_info") and len( cgi.path_info ) ) request.goingTo.pageName = cgi.path_info;
		else if ( structKeyExists( url, "page" ) ) request.goingTo.pageName = page;
		else request.goingTo.pageName = application.goto.defaultEvent;
		goto( request.goingTo.pageName );
	}
	</cfscript>
	<cfif isSimpleValue( args ) and listLen( args, "." gte 2 )>
		<cfset i = listFirst( args, "." ) />
		<cfif listLen(args, ".") gt 2> <cfset args = listDeleteAt( args, 1, "." ) /> </cfif>
		<cfswitch expression="#i#">
			<cfcase value="inject"> <cfset variables.goto = this.goto /> </cfcase>
			<cfcase value="control"><cfscript>
				i = listGetAt(args, 1, ".");
				if ( not structKeyExists( application.goto.controllers, i ) and fileExists( expandPath(application.goto.controllerPkg) & "/" & i & ".cfc" ) ) {
					goto( "trace.Controller Loaded", i );
					application.goto.controllers[ i ] = createObject( "component", application.goto.controllerPkg & "." & i );
					application.goto.controllers[ i ].goto = goto;
					application.goto.controllers[ i ].goto( "inject.methods" );
				}
				if ( structKeyExists( application.goto.controllers, i ) ) {
					i = application.goto.controllers[ i ];
					if ( args eq request.goingTo.pageName && structKeyExists( i, "requestStart" ) ) {
						if ( application.goto.showTrace ) goto( "trace.Controller Method Invoked", "#getMetadata( i ).name#.requestStart()");
						i.requestStart();	
					}
					if ( structKeyExists( i, listGetAt( args, 2, "." ) ) ) {
						request.goto.ctrlMeth = i[ listGetAt( args, 2, "." ) ];
						if ( application.goto.showTrace ) goto( "trace.Controller Method Invoked", "#getMetadata( i ).name#.#listGetAt( args, 2, "." )#()");
						i._reachAround = i[ listGetAt( args, 2, "." ) ]; i._reachAround();
					}
					goto( "view." & args );
					if ( args eq request.goingTo.pageName && structKeyExists( i, "requestEnd" ) ) {
						if ( application.goto.showTrace ) goto( "trace.Controller Method Invoked", "#getMetadata( i ).name#.requestEnd()");
						i.requestEnd();	
					}
					if ( args eq request.goingTo.pageName ) {
						writeOutput( request.goingTo.out );
						if ( application.goto.showTrace ) {
							writeOutput("<hr /><table width='100%'><tr><th style='text-align:left' nowrap>Message</th><th style='text-align:left'>Time</th><th style='text-align:left' width='100%'>Value(s)</th></tr>");
							for ( i = 1; i <= arrayLen( request.goingTo.trace ); i++) {
								writeOutput("<tr><td nowrap>#request.goingTo.trace[i].message#</td><td nowrap>#request.goingTo.trace[i].time#ms</td><td>");
								if ( arrayLen(request.goingTo.trace[i].values) eq 1 and isSimpleValue( request.goingTo.trace[i].values[1] ) )
									writeOutput( request.goingTo.trace[i].values[1] );
								else
									writeDump(request.goingTo.trace[i].values);
								writeOutput("</td></tr>");
							}
							writeOutput("</table>");
						}
					}
				}
				else{ goto( "view." & args ); }
			</cfscript></cfcase>
			<cfcase value="view">
				<cfset i = application.goto.viewDir & "/" & replaceNoCase(args, ".", "/", "all" ) & ".cfm" />
				<cfif ( fileExists( expandPath( i ) ) )>
					<cfif application.goto.showTrace> <cfset goto( "trace.View Rendered", "#i#") /> </cfif>
					<cfsavecontent variable="i"><cfinclude template="#i#" /></cfsavecontent>
					<cfset request.goingTo.out = request.goingTo.out & i />			
				</cfif>
			</cfcase>
			<cfcase value="service">
				<cfset i = application.goto.beanFactory.getBean( listGetAt(args, 2, ".") ) />
				<cfif structKeyExists( arguments, "3" )> <cfinvoke component="#i#" method="#arguments.2#" argumentCollection="#arguments.3#" returnvariable="i" />
				<cfelse> <cfinvoke component="#i#" method="#arguments.2#" returnvariable="i" /> </cfif>
				<cfif isDefined( "i" )> <cfreturn i /> </cfif>
			</cfcase>
			<cfcase value="trace"><cfscript>
				args = listDeleteAt( args, 1, "." );
				arrayAppend( request.goingTo.trace, { message = arguments[1], values = [ ], time = getTickCount() - request.goingTo.start } );
				for ( i in arguments ) { if ( arguments[i] neq args ) { arrayAppend( request.goingTo.trace[ arrayLen( request.goingTo.trace )].values, arguments[i] );} }
			</cfscript></cfcase>
			<cfdefaultcase>
				<cfif structKeyExists( arguments, "2" ) and arguments.2> <cflocation url="#cgi.script_name#?page=#args#" addToken="false" /> </cfif>
				<cfset goto( "control." & args ) />	
			</cfdefaultcase>
		</cfswitch>
	</cfif>
</cffunction>